//file name:	top_fpga.v
//author:		ETree
//date:			2017.10.1
//function:		top file of project
//log:

module top_fpga(
	//global signal                           
	input  clk,
	input  rst_n,
	
	//NET
	output e_txen,
	output [1:0] e_tx,

	input e_rxer,
	input e_rxdv,
	input e_rxclk,
	input [1:0] e_rx,
	
	//LED
	output led
	
);

//parameter define
parameter   BOARD_MAC   = 48'h00_0A_35_01_FE_C0 ;   //板卡MAC地址
parameter   BOARD_IP    = 32'h0A_0A_0A_0A       ;   //板卡IP地址
parameter   BOARD_PORT  = 16'd27181             ;   //板卡端口号
parameter   PC_MAC      = 48'hFF_FF_FF_FF_FF_FF ;   //PC机MAC地址
parameter   PC_IP       = 32'h0A_0A_0A_0F       ;   //PC机IP地址
parameter   PC_PORT     = 16'd27181             ;   //PC机端口号

//parameter of hostmot2 
parameter PWMRefWidth = 13;        // PWM resolution is PWMRefWidth-1 bits
parameter IDROMType = 3;
parameter UseStepGenPrescaler = 1'b1;
parameter UseIRQLogic = 1'b1;
parameter UseWatchDog = 1'b1;
parameter OffsetToModules = 64;
parameter OffsetToPinDesc = 448;
parameter BusWidth = 32;
parameter AddrWidth = 16;
parameter InstStride0 = 4 ;       // instance stride 0 = 4 bytes = 1 x 32 bit
parameter InstStride1 = 64;       // instance stride 1 = 64 bytes = 16 x 32 bit registers
parameter RegStride0 = 256;       // register stride 0 = 256 bytes = 64 x 32 bit registers
parameter RegStride1 = 256;       // register stride 1 = 256 bytes - 64 x 32 bit
parameter FallBack = 0;           // is this a fallback config?
 
parameter LEDCount = 1;           // lottefang
parameter IOWidth = 72;           // lottefang
parameter ClockLow = 50000000;    // lottefang
parameter ClockHigh = 100000000;  // lottefang
parameter ClockMed = 50000000;    // lottefang
parameter LIOWidth = 0;           // lottefang
parameter IOPorts = 2;            // lottefang
parameter SepClocks = 1'b1;          // lottefang
parameter OneWS = 1'b0;              // lottefang
parameter FPGAPins = 144;         // lottefang
parameter PortWidth = 24;         // lottefang
parameter BoardNameLow = 32'h4153454D;  // lottefang
parameter BoardNameHigh = 32'h30394937; // lottefang
parameter FPGASize = 9;

//wire define
wire            rec_end         ;   //单包数据接收完成信号
wire            rec_en          ;   //接收数据使能信号
wire   [31:0]   rec_data        ;   //接收数据
wire   [15:0]   rec_data_num    ;   //接收有效数据字节数
wire            send_end        ;   //发送完成信号
wire            read_data_req   ;   //读数据请求信号
wire            send_en         ;   //数据开始发送信号
wire   [31:0]   send_data       ;   //发送数据
wire            eth_rxdv        ;   //输入数据有效信号(mii)
wire    [3:0]   eth_rx_data     ;   //输入数据(mii)
wire            eth_tx_en       ;   //输出数据有效信号(mii)
wire    [3:0]   eth_tx_data     ;   //输出数据(mii)

//reg   define
reg             clk_25m         ;   //mii时钟
	
//clk_25m:mii时钟
always @(negedge e_rxclk or negedge rst_n)
    if(~rst_n)
        clk_25m <=  1'b0;
    else
        clk_25m <= ~clk_25m;
		  

//------------- eth_udp_inst -------------
eth_udp
#(
    .BOARD_MAC      (BOARD_MAC      ),  //板卡MAC地址
    .BOARD_IP       (BOARD_IP       ),  //板卡IP地址
    .BOARD_PORT     (BOARD_PORT     ),  //板卡端口号
    .PC_MAC         (PC_MAC         ),  //PC机MAC地址
    .PC_IP          (PC_IP          ),  //PC机IP地址
    .PC_PORT        (PC_PORT        )   //PC机端口号
)
eth_udp_inst
(
    .eth_rx_clk     (clk_25m        ),  //mii时钟,接收
    .rst_n          (rst_n          ),  //复位信号,低电平有效
    .eth_rxdv       (eth_rxdv       ),  //输入数据有效信号(mii)
    .eth_rx_data    (eth_rx_data    ),  //输入数据(mii)
    .eth_tx_clk     (clk_25m        ),  //mii时钟,发送
    .send_en        (rec_end        ),  //开始发送信号
    .send_data      (send_data      ),  //发送数据
    .send_data_num  (rec_data_num   ),  //发送有效数据字节数

    .send_end       (send_end       ),  //单包数据发送完成信号
    .read_data_req  (read_data_req  ),  //读数据请求信号
    .rec_end        (rec_end        ),  //单包数据接收完成信号
    .rec_en         (rec_en         ),  //接收数据使能信号
    .rec_data       (rec_data       ),  //接收数据
    .rec_data_num   (rec_data_num   ),  //接收有效数据字节数
    .eth_tx_en      (eth_tx_en      ),  //输出数据有效信号(mii)
    .eth_tx_data    (eth_tx_data    )   //输出数据(mii)
);		  
		  
//------------- mii_to_rmii_inst -------------
mii_to_rmii mii_to_rmii_inst
(
    .eth_mii_clk    (clk_25m        ),  //mii时钟
    .eth_rmii_clk   (e_rxclk        ),  //rmii时钟
    .rst_n          (rst_n          ),  //复位信号
    .tx_dv          (eth_tx_en      ),  //输出数据有效信号(mii)
    .tx_data        (eth_tx_data    ),  //输出有效数据(mii)

    .eth_tx_dv      (e_txen         ),  //输出数据有效信号(rmii)
    .eth_tx_data    (e_tx           )   //输出数据(rmii)
);
	 
//------------- rmii_to_mii_inst -------------
rmii_to_mii rmii_to_mii_inst
(
    .eth_rmii_clk   (e_rxclk        ),  //rmii时钟
    .eth_mii_clk    (clk_25m        ),  //mii时钟
    .rst_n          (rst_n          ),  //复位信号
    .rx_dv          (e_rxdv         ),  //输入数据有效信号(rmii)
    .rx_data        (e_rx           ),  //输入数据(rmii)

    .eth_rx_dv      (eth_rxdv       ),  //输入数据有效信号(mii)
    .eth_rx_data    (eth_rx_data    )   //输入数据(mii)
);
		  
		  
//------------- fifo_inst -------------
//fifo模块，用于缓存单包数据
//my_fifo    my_fifo_inst
//(
//    .aclr           (~rst_n        ),  //fifo清零信号
//    .wrclk          (clk_25m        ),  //fifo写时钟
//    .wrreq          (rec_en         ),  //fifo写请求
//    .data           (rec_data       ),  //fifo写数据
//
//    .rdclk          (clk_25m        ),  //fifo读时钟
//    .rdreq          (read_data_req  ),  //fifo读请求
//    .q              (send_data      )   //fifo读数据
//);

HostMot2 #(
    .idromtype(IDROMType),
    .sepclocks(SepClocks),
    .onews(OneWS),
    .usestepgenprescaler(UseStepGenPrescaler),
    .useirqlogic(UseIRQLogic),
    .pwmrefwidth(PWMRefWidth),
    .usewatchdog(UseWatchDog),
    .offsettomodules(OffsetToModules),
    .offsettopindesc(OffsetToPinDesc),
    .clockhigh(ClockHigh),
    .clockmed(ClockMed),
    .clocklow(ClockLow),
    .boardnamelow(BoardNameLow),
    .boardnamehigh(BoardNameHigh),
    .fpgasize(FPGASize),
    .fpgapins(FPGAPins),
    .ioports(IOPorts),
    .iowidth(IOWidth),
    .liowidth(LIOWidth),
    .portwidth(PortWidth),
    .buswidth(BusWidth),
    .addrwidth(AddrWidth),
    .inststride0(InstStride0),
    .inststride1(InstStride1),
    .regstride0(RegStride0),
    .regstride1(RegStride1),
    .ledcount(LEDCount)
	 )
ahostmot2 (
    .ibus(rec_data),
    .obus(send_data),
    .addr(),
    .readstb(rec_en),
    .writestb(read_data_req),
    .clklow(clk_25m),        // I/O clock
    .clkmed(clk_25m),       // Processor clock
    .clkhigh(),        // PWM clock
    // .int(INT),           // Uncomment if needed
    // .iobits(IOBITS),     // lottefang 暂时不研究IO
    .leds(LEDS)
);

endmodule


